{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d2623dee-249c-4ce9-ab49-b7148ad4b62c",
   "metadata": {},
   "source": [
    "<center><img src=\"./image/CLBLOGO.jpg\" alt=\"创乐博\" style=\"width: 300px;\"/></center>\n",
    "\n",
    "# 7.机器人视觉巡线\n",
    "\n",
    "@－－－－湖南创乐博智能科技有限公司－－－－<br>\n",
    "@  文件名：7.机器人视觉巡线.py <br>\n",
    "@  版本：V2.0 <br>\n",
    "@  author: zhulin<br>\n",
    "@  说明：机器人视觉巡线\n",
    "机器人基本运动！<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf457d17-881d-4721-a055-966a0fbf3fa7",
   "metadata": {},
   "source": [
    "## 1.载入必要的库"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "76cc4e64-38c6-417e-b258-bca3ac8ee6bb",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import cv2\n",
    "from LOBOROBOT import LOBOROBOT # 载入机器人库\n",
    "from gpiozero import Button\n",
    "from gpiozero import LED\n",
    "import time \n",
    "import threading # 线程\n",
    "import ctypes\n",
    "import inspect"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "64d29847-2021-4139-bd6c-cd8c35f20562",
   "metadata": {},
   "source": [
    "## 2.bgr转jpeg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "ad4fb034-a694-4d75-9883-a43563e01386",
   "metadata": {},
   "outputs": [],
   "source": [
    "def bgr8_to_jpeg(value, quality=75):\n",
    "    return bytes(cv2.imencode('.jpg', value)[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a8c8b3ed-16f4-4f26-875d-f8beec6d1e49",
   "metadata": {},
   "source": [
    "## 线程结束代码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "8c6ae664-10c0-4899-a925-367693901581",
   "metadata": {},
   "outputs": [],
   "source": [
    "def _async_raise(tid, exctype):\n",
    "    tid = ctypes.c_long(tid)\n",
    "    if not inspect.isclass(exctype):\n",
    "        exctype = type(exctype)\n",
    "    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))\n",
    "    if res == 0:\n",
    "        raise ValueError(\"invalid thread id\")\n",
    "    elif res != 1:\n",
    "        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)\n",
    "        raise SystemError(\"PyThreadState_SetAsyncExc failed\")\n",
    "        \n",
    "def stop_thread(thread):\n",
    "    _async_raise(thread.ident, SystemExit)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "0a2a8c03-b8b5-4a68-b30b-59dc9072a3e0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 按键及LED初始化\n",
    "Btn  = Button(19,pull_up=True)   # 按键端口\n",
    "Gpin    = LED(5)\n",
    "Rpin    = LED(6)\n",
    "\n",
    "#初始化舵机\n",
    "clbrobot = LOBOROBOT()  # 实例化机器人对象\n",
    "clbrobot.t_stop(0)  # 停止"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6a9ed0ea-48e0-469c-ad30-a3278934da3c",
   "metadata": {},
   "source": [
    "## 控制舵机的角度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "a6a0bd5c-95dc-4bb8-9f0c-826fa83242cb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Configure min and max servo pulse lengths\n",
    "servo_min = 150  # Min pulse length out of 4096\n",
    "servo_max = 600  # Max pulse length out of 4096\n",
    "\n",
    "# 频率设置为50hz，适用于舵机系统。\n",
    "clbrobot.set_servo_angle(10,90)  # 底座舵机 90 \n",
    "clbrobot.set_servo_angle(9,50)  # 顶部舵机 145\n",
    "time.sleep(0.5)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "be10d2c9-c8f7-4546-a126-6df065f6f6c5",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 按键标志位\n",
    "keyflag = 0\n",
    "\n",
    "# 按键控制函数\n",
    "def keysacn():\n",
    "    global keyflag\n",
    "    print('*****************************************') \n",
    "    print('* makerobo Button Pressed!*') \n",
    "    print('*****************************************')\n",
    "    Rpin.on()  # 打开红色LED\n",
    "    Gpin.off() # 关闭绿色LED\n",
    "    keyflag = 1   # 按键标志位置1\n",
    "\n",
    "def released():\n",
    "    print(\"button was released\")\n",
    "    Rpin.off()   # 关闭红色LED\n",
    "    Gpin.on()    # 打开绿色LED\n",
    "\n",
    "# 按键中断函数\n",
    "Btn.when_pressed = keysacn\n",
    "Btn.when_released = released"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "f7cc90a4-fb3b-476a-ab6a-bb7dfdc4994e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "78250721bc8d4e2cbd8cc1020da37762",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Image(value=b'', format='jpeg', height='120', width='160')"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 载入显示库\n",
    "import ipywidgets.widgets as widgets\n",
    "from IPython.display import display\n",
    "import libcamera\n",
    "from picamera2 import Picamera2\n",
    "\n",
    "image = widgets.Image(format='jpeg', width=160, height=120)\n",
    "display(image)\n",
    "\n",
    "def bgr8_to_jpeg(value, quality=75):\n",
    "    return bytes(cv2.imencode('.jpg', value)[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "eb1a593a-ce95-4a31-ad22-d49b2f43a3c7",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[0:01:22.929982464] [5940] \u001b[1;32m INFO \u001b[1;37mCamera \u001b[1;34mcamera_manager.cpp:284 \u001b[0mlibcamera v0.1.0+118-563cd78e\n",
      "[0:01:22.943012659] [7812] \u001b[1;32m INFO \u001b[1;37mRPI \u001b[1;34mpisp.cpp:653 \u001b[0mlibpisp version v1.0.2 fa44a258644a 22-11-2023 (21:59:22)\n",
      "[0:01:22.957081759] [7812] \u001b[1;32m INFO \u001b[1;37mRPI \u001b[1;34mpisp.cpp:1112 \u001b[0mRegistered camera /base/axi/pcie@120000/rp1/i2c@80000/ov5647@36 to CFE device /dev/media2 and ISP device /dev/media1 using PiSP variant BCM2712_C0\n",
      "[0:01:22.959597358] [5940] \u001b[1;32m INFO \u001b[1;37mCamera \u001b[1;34mcamera_manager.cpp:284 \u001b[0mlibcamera v0.1.0+118-563cd78e\n",
      "[0:01:22.970767912] [7817] \u001b[1;32m INFO \u001b[1;37mRPI \u001b[1;34mpisp.cpp:653 \u001b[0mlibpisp version v1.0.2 fa44a258644a 22-11-2023 (21:59:22)\n",
      "[0:01:22.984059306] [7817] \u001b[1;32m INFO \u001b[1;37mRPI \u001b[1;34mpisp.cpp:1112 \u001b[0mRegistered camera /base/axi/pcie@120000/rp1/i2c@80000/ov5647@36 to CFE device /dev/media2 and ISP device /dev/media1 using PiSP variant BCM2712_C0\n",
      "[0:01:22.988750240] [5940] \u001b[1;33m WARN \u001b[1;37mV4L2 \u001b[1;34mv4l2_pixelformat.cpp:338 \u001b[0mUnsupported V4L2 pixel format Y16 \n",
      "[0:01:22.988819382] [5940] \u001b[1;33m WARN \u001b[1;37mV4L2 \u001b[1;34mv4l2_pixelformat.cpp:338 \u001b[0mUnsupported V4L2 pixel format RGB6\n",
      "[0:01:22.988824789] [5940] \u001b[1;33m WARN \u001b[1;37mV4L2 \u001b[1;34mv4l2_pixelformat.cpp:338 \u001b[0mUnsupported V4L2 pixel format BGR6\n",
      "[0:01:22.988831307] [5940] \u001b[1;33m WARN \u001b[1;37mV4L2 \u001b[1;34mv4l2_pixelformat.cpp:338 \u001b[0mUnsupported V4L2 pixel format PC1M\n",
      "[0:01:22.989633843] [5940] \u001b[1;32m INFO \u001b[1;37mCamera \u001b[1;34mcamera.cpp:1183 \u001b[0mconfiguring streams: (0) 160x120-RGB888 (1) 1920x1080-SRGGB16\n",
      "[0:01:22.989869599] [7817] \u001b[1;32m INFO \u001b[1;37mRPI \u001b[1;34mpisp.cpp:1396 \u001b[0mSensor: /base/axi/pcie@120000/rp1/i2c@80000/ov5647@36 - Selected sensor format: 1920x1080-SRGGB10_1X10 - Selected CFE format: 1920x1080-RG16\n"
     ]
    }
   ],
   "source": [
    "picamera = Picamera2()\n",
    "config = picamera.create_preview_configuration(main={\"format\": 'RGB888', \"size\": (160, 120)},\n",
    "                                               raw={\"format\": \"SRGGB12\", \"size\": (1920, 1080)})\n",
    "config[\"transform\"] = libcamera.Transform(hflip=0, vflip=1)\n",
    "picamera.configure(config)\n",
    "picamera.start()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "22799eea-9a52-4391-8f9e-9a253177de34",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "def Video_display():\n",
    "    while 1:\n",
    "        if keyflag == 1:\n",
    "            # Capture the frames\n",
    "            frame = picamera.capture_array()\n",
    "            frame=cv2.flip(frame, 1) \n",
    "            # Crop the image\n",
    "            crop_img =frame[60:120, 0:160]\n",
    "            # Convert to grayscale\n",
    "            gray = cv2.cvtColor(crop_img, cv2.COLOR_BGR2GRAY)\n",
    "            # Gaussian blur\n",
    "            blur = cv2.GaussianBlur(gray,(5,5),0)\n",
    "            # Color thresholding\n",
    "            ret,thresh1 = cv2.threshold(blur,60,255,cv2.THRESH_BINARY_INV)\n",
    "            # Erode and dilate to remove accidental line detections\n",
    "            mask = cv2.erode(thresh1, None, iterations=2)\n",
    "            mask = cv2.dilate(mask, None, iterations=2)\n",
    "            \n",
    "           # Find the contours of the frame\n",
    "            contours,hierarchy = cv2.findContours(mask.copy(), 1, cv2.CHAIN_APPROX_NONE)\n",
    "            # Find the biggest contour (if detected)\n",
    "            if len(contours) > 0:\n",
    "                c = max(contours, key=cv2.contourArea)\n",
    "                M = cv2.moments(c)\n",
    "                \n",
    "                cx = int(M['m10']/M['m00'])\n",
    "                cy = int(M['m01']/M['m00'])\n",
    "                \n",
    "                cv2.line(crop_img,(cx,0),(cx,720),(255,0,0),1)\n",
    "                cv2.line(crop_img,(0,cy),(1280,cy),(255,0,0),1)\n",
    "                \n",
    "                cv2.drawContours(crop_img, contours, -1, (0,255,0), 1)\n",
    "                \n",
    "                if cx >= 120:\n",
    "                    clbrobot.turnRight(30,0)                 \n",
    "                    print(\"Turn Left!\")\n",
    "                if cx < 120 and cx > 50:\n",
    "                    clbrobot.t_up(50,0)\n",
    "                    print(\"On Track!\")\n",
    "                if cx <= 50:\n",
    "                    clbrobot.turnLeft(30,0)   \n",
    "                    print(\"Turn Right\")\n",
    "            else:\n",
    "                print(\"I don't see the line\")   \n",
    "                \n",
    "            image.value = bgr8_to_jpeg(crop_img)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "74e261dc-d8f6-4082-8c45-de8ba48ac700",
   "metadata": {},
   "source": [
    "## 开启线程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "bf3439a2-ce87-452e-ade4-22dee8c1b65d",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_5940/3481196328.py:2: DeprecationWarning: setDaemon() is deprecated, set the daemon attribute instead\n",
      "  t.setDaemon(True)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "button was released\n",
      "*****************************************\n",
      "* makerobo Button Pressed!*\n",
      "*****************************************\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n",
      "Turn Left!\n"
     ]
    }
   ],
   "source": [
    "t = threading.Thread(target=Video_display)\n",
    "t.setDaemon(True)\n",
    "t.start()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a017100-4fac-483f-ad9c-18d1a91ed86f",
   "metadata": {},
   "source": [
    "## 结束线程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "ba599623-b29a-4fe3-a72a-6f35b414a435",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Turn Left!\n",
      "Turn Left!\n"
     ]
    }
   ],
   "source": [
    "stop_thread(t)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "59a71fde-9836-4a05-a82f-f81349d1d5cc",
   "metadata": {},
   "source": [
    "## 关闭电机"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "3b23948a-3364-4b4d-a8bc-ba050e3f85bf",
   "metadata": {},
   "outputs": [],
   "source": [
    "clbrobot.t_stop(0)       "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
